有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java casting Integer>Object和更高版本的Object>Integer

下面是AVL树实现的代码片段。它在过去工作得很好,但现在不再工作了。原因似乎是将对象转换为整数

因此,Avl结构将对象作为数据处理,用户(在本例中为main())进行转换。我想要实现的是一个具有可比较对象的通用AVL树。实际上,我在插入对象的同时还插入了一个键,以便能够区分要排序的内容。它们在内部被放入一个名为KeyData的本地类中

以下是代码:

  // private stuff above - not interesting for problem

  // Public AVL tree methods

  public void insert(Object thedata, String thekey) {
    internal_insert(new KeyData(thedata, thekey));
  }

  public Object find(String key) {
    Object ret = null;
    KeyData x = new KeyData(null, key);
    if(data != null) {
      if(x.compareTo(data) == 0)
    ret = data;
      else if(x.compareTo(data) < 0) {
    if(left != null)
      ret = left.find(key);
      } else {
    if(right != null)
      ret = right.find(key);
      }
    }
    return ret;
  }

  public Object[] inorder() {
    Vector<Object> v = new Vector<Object>();
    iinorder(v);
    return v.toArray();
  }

  public static void main(String[] args) {
    Avl test = new Avl();
    test.insert(Integer.valueOf(1090), "1");
    test.insert(Integer.valueOf(343452), "2");
    test.insert(Integer.valueOf(3345), "3");
    //Object t2 = test.find("2");
    Object lookfor = test.find("2");
    Integer t2 = (Integer) lookfor; // Line 164
    System.out.println("Got: " + t2.toString());
  }

结果如下:

$ java Avl
Exception in thread "main" java.lang.ClassCastException: 
    class Avl$KeyData cannot be cast to class java.lang.Integer (Avl$KeyData is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
    at Avl.main(Avl.java:164)

。。。那故事是什么


共 (1) 个答案

  1. # 1 楼答案

    ...so what's the story?

    简短的版本是find方法不返回Integer值。所以你不能把它转换成^{

    It worked fine back in the days, but now it doesn't work any longer.

    那么,从那时到现在,你的代码中一定有一些重要的变化。(提示:Java语言或其实现并没有改变导致这种情况的方式!)

    让我们看看find方法

    public Object find(String key) {
        Object ret = null;
        KeyData x = new KeyData(null, key);
        if (data != null) {
            if (x.compareTo(data) == 0)
                ret = data;
            else if (x.compareTo(data) < 0) {
                if (left != null)
                    ret = left.find(key);
            } else {
                if (right != null)
                    ret = right.find(key);
            }
        }
        return ret;
    }
    

    第一个观察结果是,你的方法最初的缩进是一团糟。糟糕的缩进让你的代码很难让每个人阅读。。。并且理解。我已经修好了

    所以find方法是递归地搜索一棵树,当它找到匹配项时。它返回data是什么。我看不到Data字段的声明,但证据是它是Avl.KeyData的一个实例。(这是有道理的……因为您将datax进行比较,后者是KeyData实例。)

    无论如何,这解释了为什么结果不是Integer

    您没有向我们展示KeyData类,但我猜它有一个value字段,它是/应该是Integer。这就是你应该回报的。找到的KeyData对象的值字段的内容

    但这里最大的问题是你对Object的使用。正如@NomadMaker所评论的,这实际上应该是一个泛型类型,其类型参数将是树中值的类型。那么你就不必在main中使用类型转换了。。。编译器会告诉你find返回KeyData<V>而不是V是不正确的

    (您的实现还有一些其他问题……但这不是一个“诊所”。)